#include "WMIConnection.h"

using namespace std;
using namespace log4cxx;
using namespace log4cxx::xml;
using namespace log4cxx::helpers;

WHResult* 
WMIConnection::executeQuery(const wchar_t* wql_query)
{
	DOMConfigurator::configure("LogConfig.xml");
	HRESULT hres;
	LoggerPtr loggerWConn(Logger::getLogger("loggerWConn"));
	stringstream out;

	hres = _pSvc->ExecQuery(
		bstr_t(WQL.c_str()), 
        bstr_t(wql_query),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &_pEnumerator);

	
    if (FAILED(hres))
    {
        WHResult* whres = new WHResult(QUERY_FAILED, hres);
        LOG4CXX_ERROR(loggerWConn, whres->toString());
        close();        
		CoUninitialize();
        return whres;               // Program has failed.
    }

// Step 8: -------------------------------------------------
    // Secure the enumerator proxy
   hres = CoSetProxyBlanket(       
       _pEnumerator,                         // the proxy to set
       RPC_C_AUTHN_WINNT,            // authentication service
       RPC_C_AUTHZ_NONE,             // authorization service
       NULL,                         // Server principal name
       RPC_C_AUTHN_LEVEL_CALL,       // authentication level
       RPC_C_IMP_LEVEL_IMPERSONATE,  // impersonation level
       NULL,                         // client identity 
       EOAC_NONE                     // proxy capabilities     
    );

    if (FAILED(hres))
    {
        WHResult* whres = new WHResult(PROXY_NOT_SET, hres);
		LOG4CXX_ERROR(loggerWConn, whres->toString());
		close();
        return whres;               // Program has failed.
    }

	return new WHResult(W_OK, 0);
}

WHResult* 
WMIConnection::getClassObject(const wchar_t* className,IWbemClassObject** classObject)
{
	DOMConfigurator::configure("LogConfig.xml");
	HRESULT hres;	
	LoggerPtr loggerWConn(Logger::getLogger("loggerWConn"));
	stringstream out;

	BSTR Name =(BSTR) className;

	hres = _pSvc->GetObject(Name, 0, NULL, classObject, NULL);

	
    if (FAILED(hres))
    {
        WHResult* whres = new WHResult(QUERY_FAILED, hres);
        LOG4CXX_ERROR(loggerWConn, whres->toString());
        _pSvc->Release();
		CoUninitialize();
        return whres;               // Program has failed.
    }

// Step 8: -------------------------------------------------
    // Secure the enumerator proxy
    //hres = CoSetProxyBlanket(
    //    _pEnumerator,                    // Indicates the proxy to set
    //    RPC_C_AUTHN_DEFAULT,            // RPC_C_AUTHN_xxx
    //    RPC_C_AUTHZ_DEFAULT,            // RPC_C_AUTHZ_xxx
    //    COLE_DEFAULT_PRINCIPAL,         // Server principal name 
    //    RPC_C_AUTHN_LEVEL_PKT_PRIVACY,  // RPC_C_AUTHN_LEVEL_xxx 
    //    RPC_C_IMP_LEVEL_IMPERSONATE,    // RPC_C_IMP_LEVEL_xxx
    //    _userAcct,                       // client identity
    //    EOAC_NONE                       // proxy capabilities 
    //    );

    //if (FAILED(hres))
    //{
    //    cout << "Could not set proxy blanket on enumerator. Error code = 0x" 
    //         << hex << hres << endl;
    //    _pEnumerator->Release();
    //    _pSvc->Release();
    //    _pLoc->Release();     
    //    CoUninitialize();
    //    return hres;               // Program has failed.
    //}

	return new WHResult(W_OK, 0);
}

void 
WMIConnection::close()
{	
	if (_pEnumerator != NULL)
		_pEnumerator->Release();
	// if (_pSvc != NULL)
	//	_pSvc->Release();

	//if (_pLoc != NULL)
	//	_pLoc->Release();

	CoUninitialize();
}